import AppUtil from "../AppUtil"
import Singleton from "../base/Singleton"


const KEY_VOLUME_MUSIC = 'app_volume_music'
const KEY_VOLUME_EFFECT = 'app_volume_effect'
const KEY_ENABLE_MUSIC = 'app_enable_music'
const KEY_ENABLE_EFFECT = 'app_enable_effect'


/**
 * @description 音乐音效管理器
 * @author mirahs
 * @email 2892727493@qq.com
 */
export default class AudioMgr extends Singleton {
    public static get inst() {
        return super.getInstance<AudioMgr>()
    }


    // 音乐音量大小
    private musicVolume: number = 1
    // 音效音量大小
    private effectVolume: number = 1

    private musicEnable: boolean = true
    private effectEnable: boolean = true


    constructor() {
        super()

        var t = cc.sys.localStorage.getItem(KEY_VOLUME_MUSIC)
        if (t) this.musicVolume = parseFloat(t)

        var t = cc.sys.localStorage.getItem(KEY_VOLUME_EFFECT)
        if (t) this.effectVolume = parseFloat(t)

        var t = cc.sys.localStorage.getItem(KEY_ENABLE_MUSIC)
        this.musicEnable = t != 'false'
        !this.musicEnable && cc.audioEngine.setMusicVolume(0)

        var t = cc.sys.localStorage.getItem(KEY_ENABLE_EFFECT)
        this.effectEnable = t != 'false'
        !this.effectEnable && cc.audioEngine.setEffectsVolume(0)

        cc.game.on(cc.game.EVENT_HIDE, this.pauseAll)
        cc.game.on(cc.game.EVENT_SHOW, this.resumeAll)
    }


    public playMusic(clip: cc.AudioClip) {
        this.stopMusic()

        cc.audioEngine.playMusic(clip, true)
    }

    public stopMusic() {
        cc.audioEngine.stopMusic()
    }

    public playEffect(clip: cc.AudioClip, loop: boolean = false, cb?: Function): number {
        const audioId = cc.audioEngine.playEffect(clip, loop)

        if (cb) {
            cc.audioEngine.setFinishCallback(audioId, cb)
        }

        return audioId
    }

    public stopEffect(audioId: number) {
        cc.audioEngine.stopEffect(audioId)
    }

    public getEffectDuration(audioId: number): number {
        return cc.audioEngine.getDuration(audioId)
    }

    public getMusicVolume(): number {
        return this.musicEnable ? this.musicVolume : 0
    }

    public setMusicVolume(val: number, force: boolean = false) {
        if (this.musicVolume == val && !force) return

        this.musicVolume = val
        cc.audioEngine.setMusicVolume(val)
        cc.sys.localStorage.setItem(KEY_VOLUME_MUSIC, val)
    }

    public getEffectVolume(): number {
        return this.effectVolume ? this.musicVolume : 0
    }

    public setEffectVolume(val: number, force: boolean = false) {
        if (this.effectVolume == val && !force) return

        this.effectVolume = val
        cc.audioEngine.setEffectsVolume(val)
        cc.sys.localStorage.setItem(KEY_VOLUME_EFFECT, val)
    }


    public toogleMusicFlag() {
        this.musicEnable = !this.musicEnable
        if (this.musicEnable) {
            cc.audioEngine.setMusicVolume(this.musicVolume)
        } else {
            cc.audioEngine.setMusicVolume(0)
        }

        AppUtil.storeSet(KEY_ENABLE_MUSIC, this.musicEnable)
    }

    public getMusicFlag(): boolean {
        return this.musicEnable
    }

    public toogleEffectFlag() {
        this.effectEnable = !this.effectEnable
        if (this.effectEnable) {
            cc.audioEngine.setEffectsVolume(this.effectVolume)
        } else {
            cc.audioEngine.setEffectsVolume(0)
        }

        AppUtil.storeSet(KEY_ENABLE_EFFECT, this.effectEnable)
    }

    public getEffectFlag(): boolean {
        return this.effectEnable
    }


    public pauseAll() {
        cc.audioEngine.pauseAll()
    }

    public resumeAll() {
        cc.audioEngine.resumeAll()
    }
}
